package com.simtop.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.simtop.common.ServerResponse;
import com.simtop.dao.CountDao;
import com.simtop.dao.OperateDao;
import com.simtop.dao.UserDao;
import com.simtop.pojo.logpo.Operate;
import com.simtop.pojo.userpo.User;
import com.simtop.pojo.userpo.Users;
import com.simtop.pojo.userpo.Userse;
import com.simtop.service.UserService;
import com.simtop.util.emailutil.AliyunMailUtil;
import com.simtop.util.encryptionutil.SHA256Util;
import com.simtop.util.emailutil.SmsRandomCodeUtil;
import com.simtop.vo.uservo.UserParamsVo;
import com.simtop.vo.uservo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserDao userDao;

    @Autowired
    private OperateDao operateDao;

    @Autowired
    private CountDao countDao;

    @Override
    public ServerResponse<Object> importUsers2(List<Object> users) {
        try {
            /**
             * 这里仅仅临时导入数据,没有进行邮箱号的判断等，不完善。
             *
             *
             *
             *
             */
            for (Object obj2 : users) {
                Userse users2 = (Userse) obj2;
                //校验
                int resultCount = userDao.checkLoginName(users2.getLoginName());
                if (resultCount > 0) {
                    return ServerResponse.createByErrorMsg("登陆用户名: "+users2.getLoginName()+" 已存在,批量插入失败");
                }
                resultCount = userDao.checkEmail(users2.getEmail());
                if (resultCount > 0) {
                    return ServerResponse.createByErrorMsg("邮箱: "+users2.getEmail()+" 已存在,批量插入失败");
                }

            }



            for (Object obj : users) {
                Userse users1 = (Userse) obj;
                users1.setRoleId(4);
                users1.setPassword(SHA256Util.generateShaPwd(users1.getPassword()));
                userDao.insertBackUser2(users1);
            }
            return ServerResponse.createBySuccess("导入成功");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            return ServerResponse.createByErrorMsg("导入失败");
        }
    }


    /**
     * 注册业务逻辑类
     *
     * @param userVo
     * @return
     */
    @Override
    public ServerResponse<String> register(UserVo userVo) {
        //保证验证码不能为空
        if (userVo.getCheckCode() == null || "".equals(userVo.getCheckCode())) {
            return ServerResponse.createByErrorMsg("验证码不能为空");
        }
        //前端传递的验证码和redis中的checkCode进行比对
        if (!userVo.getCheckCode().equals(redisTemplate.boundValueOps("email_" + userVo.getEmail()).get())) {
            return ServerResponse.createByErrorMsg("验证码错误");
        }
        if (userVo.getLoginName() == null || userVo.getLoginName().equals("")) {
            return ServerResponse.createByErrorMsg("登陆用户名不能为空");
        }
        if (userVo.getEmail() == null || userVo.getEmail().equals("")) {
            return ServerResponse.createByErrorMsg("邮箱不能为空");
        }

        //用户名、邮箱需要唯一
        int resultCount = userDao.checkLoginName(userVo.getLoginName());
        if (resultCount > 0) {
            return ServerResponse.createByErrorMsg("登陆用户名已存在");
        }
        resultCount = userDao.checkEmail(userVo.getEmail());
        if (resultCount > 0) {
            return ServerResponse.createByErrorMsg("邮箱已存在");
        }
        //userVo <- User
        User user = new User();
        user.setSchool(userVo.getSchool());
        user.setEmail(userVo.getEmail());
        //密码
        user.setPassword(SHA256Util.generateShaPwd(userVo.getPassword()));
        user.setCity(userVo.getCity());
        user.setProvince(userVo.getProvince());
        user.setLoginName(userVo.getLoginName());
        user.setUsername(userVo.getUsername());
        user.setRoleId(userVo.getRoleId());
        user.setGrade(userVo.getGrade());
        resultCount = userDao.insert(user);
        if (resultCount < 0) {
            Operate operate = new Operate("用户注册", user.getUsername(), user.getRoleId(), "注册失败", new Date(), JSONObject.toJSONString(user));
            operateDao.insertOperate(operate);
            return ServerResponse.createByErrorMsg("用户注册失败");
        }
        Operate operate = new Operate("用户注册", user.getUsername(), user.getRoleId(), "注册成功", new Date(), JSONObject.toJSONString(user));
        operateDao.insertOperate(operate);
        return ServerResponse.createBySuccessMsg("注册成功");
    }

    /**
     * 邮箱注册验证码生成逻辑类
     *
     * @param email
     * @return
     */
    @Override
    public ServerResponse<String> generateCheckCode(String email) {
        synchronized (this) {
            //邮箱非空验证
            if (email == null || "".equals(email)) {
                return ServerResponse.createByErrorMsg("邮箱不能为空,请填入有效地址");
            }
            int resultCount2 = userDao.checkEmail(email);
            if (resultCount2 > 0) {
                return ServerResponse.createByErrorMsg("邮箱已存在");
            }
            //生成随机的6位数字验证码
            String verificationCode = SmsRandomCodeUtil.generateRandomSixNum();
            //调用邮箱发送
            AliyunMailUtil.sendMail(email, "题库系统注册", "您的验证码为：" + verificationCode + "。此验证码三分钟内有效，请及时注册。" + "<br><br>" + "本邮件是系统自动发送的，请勿直接回复！感谢您的注册，祝您使用愉快！");
            redisTemplate.boundValueOps("email_" + email).set(verificationCode, 180, TimeUnit.SECONDS);
            return ServerResponse.createBySuccessMsg("邮件发送成功");
        }
    }

    /**
     * 忘记密码时候，根据邮箱返回验证码
     *
     * @param email
     * @return
     */
    @Override
    public ServerResponse<String> forgetSendEmailCode(String email) {
        //验证邮箱是否存在
        int resultCount = userDao.checkEmail(email);
        if (resultCount != 1) {
            return ServerResponse.createByErrorMsg("邮箱不存在！");
        }
        //邮箱非空验证
        if (email == null || "".equals(email)) {
            return ServerResponse.createByErrorMsg("邮箱不能为空,请填入有效地址");
        }
        //生成随机的验证码
        String verificationCode = SmsRandomCodeUtil.generateRandomSixNum();
        //调用邮箱发送
        AliyunMailUtil.sendMail(email, "题库系统密码重置", "您的验证码为：" + verificationCode + "。此验证码三分钟内有效，请及时重置密码。" + "<br><br>" + "本邮件是系统自动发送的，请勿直接回复！");
        //发送成功保存邮箱地址对应的验证码 todo 3分钟 已解决
        redisTemplate.boundValueOps("forget_" + email).set(verificationCode, 180, TimeUnit.SECONDS);
        return ServerResponse.createBySuccessMsg("邮件发送成功");
    }

    @Override
    public List<User> findAll(User user) {
        List<User> userList = userDao.selectAll(user);
        return userList;
    }

    @Override
    public ServerResponse<String> insertBackUser(UserVo userVo) {
        System.err.println(userVo);
        // vo <- pojo
        User user = new User();
        user.setRoleId(userVo.getRoleId());
        user.setLoginName(userVo.getLoginName());
        user.setPassword(SHA256Util.generateShaPwd(userVo.getPassword()));
        user.setUsername(userVo.getUsername());
        user.setSchool(userVo.getSchool());
        user.setProvince(userVo.getProvince());
        user.setCity(userVo.getCity());
        user.setEmail(userVo.getEmail());
        user.setGrade(userVo.getGrade());
        /**
         * 查询是否存在
         */
        //用户名、邮箱需要唯一
        int resultCount1 = userDao.checkLoginName(userVo.getLoginName());
        if (resultCount1 > 0) {
            return ServerResponse.createByErrorMsg("登陆用户名已存在");
        }
        int resultCount2 = userDao.checkEmail(userVo.getEmail());
        if (resultCount2 > 0) {
            return ServerResponse.createByErrorMsg("邮箱已存在");
        }
        int resultCount = userDao.insertBackUser(user);
        if (resultCount != 1) {
            return ServerResponse.createBySuccess("新增后台用户失败");
        }
        return ServerResponse.createBySuccessMsg("新增后台用户成功");
    }

    @Override
    public ServerResponse<String> deleteByUserId(Integer id) {
        if (id == null) {
            return ServerResponse.createByErrorMsg("参数错误");
        }
        int effectNum = userDao.deleteByUserId(id);
        if (effectNum != 1) {
            return ServerResponse.createByErrorMsg("删除失败");
        }
        return ServerResponse.createBySuccess("删除成功");
    }

    @Override
    public ServerResponse<String> updateBackendUser(UserVo userVo) {
        // vo <- pojo
        User user = new User();
        user.setRoleId(userVo.getRoleId());
        user.setLoginName(userVo.getLoginName());
        //密码
        User u = userDao.findById(userVo.getId());
        if (!u.getPassword().equals(userVo.getPassword())) {
            user.setPassword(SHA256Util.generateShaPwd(userVo.getPassword()));
        } else {
            user.setPassword(userVo.getPassword());
        }
        user.setUsername(userVo.getUsername());
        user.setSchool(userVo.getSchool());
        user.setProvince(userVo.getProvince());
        user.setCity(userVo.getCity());
        user.setGrade(userVo.getGrade());
        //修改邮箱 todo 邮箱不能够唯一
        User user1 = userDao.checkLoginNameOrEmail(null, userVo.getEmail());
        if (userDao.checkEmail(userVo.getEmail()) > 0 && !user1.getId().equals(userVo.getId())) {
            return ServerResponse.createByErrorMsg("该邮箱已存在！");
        }
        user.setEmail(userVo.getEmail());
        user.setAddress(userVo.getAddress());
        user.setId(userVo.getId());
        int resultCount = userDao.updateBackendUser(user);
        if (resultCount != 1) {
            return ServerResponse.createByErrorMsg("修改后台用户失败");
        }
        return ServerResponse.createBySuccessMsg("修改后台用户成功");
    }

    @Override
    public List<User> findByParams(UserParamsVo params) {
        User user = new User();
        user.setUsername(params.getUsername());
        user.setSchool(params.getSchool());
        user.setGrade(params.getGrade());
        user.setLoginName(params.getLoginName());
        user.setRoleId(params.getRoleId());
        user.setId(params.getUserId());
        List<User> userList = userDao.selectByParams(user);
        return userList;
    }

    @Override
    public ServerResponse<Integer> accountUser() {
        int count = userDao.selectUserCounts();
        return ServerResponse.createBySuccess(count);
    }

    @Override
    public ServerResponse<User> findById(Integer id) {
        User user = userDao.findById(id);
        if (user == null) {
            return ServerResponse.createByErrorMsg("查询用户失败");
        }
        return ServerResponse.createBySuccess(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertIlabUser(UserVo userVo) {
        User user = new User();
        user.setUsername(userVo.getUsername());
        user.setLoginName(userVo.getLoginName());
        user.setSchool(userVo.getSchool());
        user.setProvince(userVo.getProvince());
        user.setCity(userVo.getCity());
        user.setRoleId(userVo.getRoleId());
        //密码
        user.setPassword(SHA256Util.generateShaPwd(userVo.getPassword()));
        user.setEmail(userVo.getEmail());
        Operate operate = new Operate("ilab平台用户登录", user.getUsername(), user.getRoleId(), "登录成功", new Date(), JSONObject.toJSONString(user));
        operateDao.insertOperate(operate);
        return userDao.inserIlabUser(user);
    }

    @Override
    public User selectUserByUserId(Integer id) {
        return userDao.findById(id);
    }

    @Override
    public User selectUserByLoginName(String loginName) {
        return userDao.findByLoginName(loginName);
    }

    @Override
    public ServerResponse<String> updatePassword(UserVo userVo) {
        String checkCode = (String) redisTemplate.boundValueOps("forget_" + userVo.getEmail()).get();
        if (!userVo.getCheckCode().equals(checkCode)) {
            return ServerResponse.createByErrorMsg("验证码错误");
        }
        if (!userVo.getNewPassword().equals(userVo.getConfirmPassword())) {
            return ServerResponse.createByErrorMsg("密码不一致，请重新输入");
        }
        User user = new User();
        user.setEmail(userVo.getEmail());
        user.setPassword(SHA256Util.generateShaPwd(userVo.getNewPassword()));
        int effectNum = userDao.updatePasswordByEmail(user);
        User use = new User();
        user.setEmail(userVo.getEmail());
        List<User> u1 = userDao.selectByParams(use);
        if (effectNum == 1) {
            Operate operate = new Operate("忘记密码操作", user.getUsername(), u1.get(0).getRoleId(), "修改成功", new Date(), JSONObject.toJSONString(user));
            operateDao.insertOperate(operate);
            return ServerResponse.createBySuccessMsg("更新密码成功");
        }
        Operate operate = new Operate("忘记密码操作", user.getUsername(), u1.get(0).getRoleId(), "修改失败", new Date(), JSONObject.toJSONString(user));
        operateDao.insertOperate(operate);
        return ServerResponse.createByErrorMsg("更新密码失败");
    }


    /**
     * 获取首页图表信息
     *
     * @return
     */
    @Override
    public ServerResponse<Object> getTopPageCount() {
        /**
         * 统计各个省份人数
         */
        List<Map<String, Integer>> map = userDao.getProvinceCount();
        /**
         * 统计各个角色用户数
         */
        List<Map<String, Integer>> roles = userDao.getRoleCount();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userProfile", map);
        jsonObject.put("userType", roles);
        return ServerResponse.createBySuccess(jsonObject);
    }

    /**
     * 导入用户信息
     *
     * @param users
     * @return
     */
    @Override
    public ServerResponse<Object> importUsers(List<Object> users) {
        try {
            /**
             * 这里仅仅临时导入数据,没有进行邮箱号的判断等，不完善。
             */
            for (Object obj : users) {
                User user = (User) obj;
                user.setPassword(SHA256Util.generateShaPwd(user.getPassword()));
                userDao.insertBackUser(user);
            }
            return ServerResponse.createBySuccess("导入成功");
        } catch (Exception e) {
            return ServerResponse.createByErrorMsg("导入失败");
        }
    }

    @Override
    public boolean updateUserName(String loginName, String userName) {
        return this.userDao.updateUserName(loginName, userName);
    }
}
